Threads in Java |
There are two typical methods to use threads in java:
Hay dos métodos típicos para usar las threads en java:
|
synchronized |
The synchronized method is used in Java to share data between threads. The following problem illustrates how to use synchronized to share the data of the PiResult class between the main thread and the worker thread. El método synchronized es usado en Java para compartir datos entre threads. El problema siguiente ilustra cómo usar synchronized para compartir los datos de la clase PiResult entre la thread principal y la thread trabajadora. |
Problem 1 |
Create a Java program called PiCompJ to compute the value of π creating a class that derives from the Thread class. Cree un programa de Java llamado PiCompJ para calcular el valor de π creando una clase que se deriva de la clase Thread. |
Step A |
Open the src folder and use the context menu to add a Java class as shown. Set the name of the class to PiCompJ. Abra la carpeta de src y use el menú de contexto para agregar una clase de Java como se muestra. Fije el nombre de la clase en PiCompj. |
Step B |
Edit the PiCompJ.java file as shownimport java.awt.*;import java.awt.event.*;import javax.swing.*; |
PiCompJ.java |
public class PiCompJ extends JFrame implements ActionListener { private JTextField tbxValue = null; private JButton btRun = null; private JButton btStop = null; private PiThread piThread = null; public PiResult piResult = null; private Timer timer = null; public PiCompJ() { this.setTitle("Calculate PI"); this.setSize(400,400); this.addWindowListener(new ExitListener()); // Container pane = this.getContentPane(); pane.setLayout(new FlowLayout()); //______________________________________________ tbxValue tbxValue = new JTextField(20); pane.add(tbxValue); //______________________________________________ btRun btRun = new JButton("Run"); pane.add(btRun); btRun.addActionListener(this); //______________________________________________ btStop btStop = new JButton("Stop"); pane.add(btStop); btStop.addActionListener(this); btStop.setEnabled(false); //______________________________ piResult = new PiResult(); timer = new Timer(1000,this); } @Override public void actionPerformed(ActionEvent e) { if(e.getSource() == btRun) // When the user clicks the Run button { btRun.setEnabled(false); btStop.setEnabled(true); this.setTitle("Running ..."); timer.start(); // piThread = new PiThread(); piThread.piResult = piResult; piThread.start(); } else if(e.getSource() == btStop)// When the user clicks the Stop button { synchronized(piResult) { piResult.cancel = true; } } else if(timer != null && e.getSource() == timer)// Call every second { synchronized(piResult) { tbxValue.setText(Double.toString(piResult.valuePi)); this.setTitle(Double.toString(piResult.progress)); } if(piThread.isAlive() == false) { timer.stop(); btRun.setEnabled(true); btStop.setEnabled(false); this.setTitle("Done!"); } } } public static void main(String[] args) { PiCompJ frame = new PiCompJ(); frame.pack(); frame.setVisible(true); } public class ExitListener extends WindowAdapter { public void windowClosing(WindowEvent e) { System.exit(0); } } // This class is used to share data between the main thread and the worker thread public class PiResult { public double valuePi; public double progress; public boolean cancel; public void PiResult() { valuePi = 0.0; progress = 0.0; cancel = false; } } public class PiThread extends Thread { PiResult piResult = null; @Override public void run() { synchronized(piResult) { piResult.progress = 0.0; piResult.cancel = false; piResult.valuePi = 0.0; } double sum = 0.0; final int maxIterations = 1000000000; boolean cancel = false; for(int i =0; i<maxIterations; i++) { //___________________________________________ Perform calculation if(i%2 == 0) sum += (1.0/(2*i+1)); else sum -= (1.0/(2*i+1)); synchronized(piResult) // update result to main thread { piResult.progress = (100.0*i)/maxIterations; cancel = piResult.cancel; piResult.valuePi = 4*sum; } if(cancel == true) break; // Stop } } } } |
Problem 24 |
Create a Java program called PiInterfaceJ to compute the value of π creating a class that implements the Runnable interface. Follow the same steps of the previous problem, and then, edit the PiInterfaceJ.java file. The program looks and runs the same as the previous problem, the main difference is that in the previous problem a class derived from Thread is created, while in this problem the main class implements the Runnable interface. Cree un programa de Java llamado PiInterfaceJ para calcular el valor de π creando una clase que implementa la interface Runnable. Siga los mismos pasos del problema previo, y entonces, edite el archivo PiInterfaceJ.java. El programa se ve y corre igual al problema previo, la diferencia principal es que en el problema anterior se crea una clase que se deriva de Thread, mientras que en este problema la clase principal implementa la interface Runnable. |
PiInterfaceJ.java |
import java.awt.*; import java.awt.event.*; import javax.swing.*; public class PiInterfaceJ extends JFrame implements ActionListener, Runnable { private JTextField tbxValue = null; private JButton btRun = null; private JButton btStop = null; private PiResult piResult = null; private Timer timer = null; private Thread thread = null; public PiInterfaceJ() { this.setTitle("Calculate PI"); this.setSize(400,400); this.addWindowListener(new ExitListener()); // Container pane = this.getContentPane(); pane.setLayout(new FlowLayout()); //______________________________________________ tbxValue tbxValue = new JTextField(20); pane.add(tbxValue); //______________________________________________ btRun btRun = new JButton("Run"); pane.add(btRun); btRun.addActionListener(this); //______________________________________________ btStop btStop = new JButton("Stop"); pane.add(btStop); btStop.addActionListener(this); btStop.setEnabled(false); //______________________________ piResult = new PiResult(); timer = new Timer(1000,this); } @Override public void actionPerformed(ActionEvent e) { if(e.getSource() == btRun) // When the user clicks the Run button { btRun.setEnabled(false); btStop.setEnabled(true); this.setTitle("Running ..."); timer.start(); // thread = new Thread(this); thread.start(); } else if(e.getSource() == btStop)// When the user clicks the Stop button { synchronized(piResult) { piResult.cancel = true; } } else if(timer != null && e.getSource() == timer)// Call every second { synchronized(piResult) { tbxValue.setText(Double.toString(piResult.valuePi)); this.setTitle(Double.toString(piResult.progress)); } if(thread.isAlive() == false) { timer.stop(); btRun.setEnabled(true); btStop.setEnabled(false); this.setTitle("Done!"); } } } @Override public void run() { synchronized(piResult) { piResult.progress = 0.0; piResult.cancel = false; piResult.valuePi = 0.0; } double sum = 0.0; final int maxIterations = 1000000000; boolean cancel = false; for(int i =0; i<maxIterations; i++) { //___________________________________________ Perform calculation if(i%2 == 0) sum += (1.0/(2*i+1)); else sum -= (1.0/(2*i+1)); synchronized(piResult) // update result to main thread { piResult.progress = (100.0*i)/maxIterations; cancel = piResult.cancel; piResult.valuePi = 4*sum; } if(cancel == true) break; // Stop } } public static void main(String[] args) { PiInterfaceJ frame = new PiInterfaceJ(); frame.pack(); frame.setVisible(true); } public class ExitListener extends WindowAdapter { public void windowClosing(WindowEvent e) { System.exit(0); } } // This class is used to share data between the main thread and the worker thread public class PiResult { public double valuePi; public double progress; public boolean cancel; public void PiResult() { valuePi = 0.0; progress = 0.0; cancel = false; } } } |